package middleware

import (
	"github.com/gin-gonic/gin"
	"github.com/gotomicro/ego/core/eapp"
	"github.com/gotomicro/ego/core/etrace"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/propagation"
	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
	"go.opentelemetry.io/otel/trace"
)

// TraceId 日志增加tid
// container := otel.DefaultConfig()
//
//	tracer := container.Build()
//	etrace.SetGlobalTracer(tracer)
func TraceId() gin.HandlerFunc {
	tracer := etrace.NewTracer(trace.SpanKindServer)
	attrs := []attribute.KeyValue{
		semconv.RPCSystemKey.String("http"),
	}
	return func(c *gin.Context) {
		// 该方法会在v0.9.0移除
		etrace.CompatibleExtractHTTPTraceID(c.Request.Header)
		ctx, span := tracer.Start(c.Request.Context(), c.Request.Method+"."+c.FullPath(), propagation.HeaderCarrier(c.Request.Header), trace.WithAttributes(attrs...))
		span.SetAttributes(
			semconv.HTTPURLKey.String(c.Request.URL.String()),
			semconv.HTTPTargetKey.String(c.Request.URL.Path),
			semconv.HTTPMethodKey.String(c.Request.Method),
			semconv.HTTPUserAgentKey.String(c.Request.UserAgent()),
			semconv.HTTPClientIPKey.String(c.ClientIP()),
			etrace.CustomTag("http.full_path", c.FullPath()),
		)
		c.Request = c.Request.WithContext(ctx)
		c.Header(eapp.EgoTraceIDName(), span.SpanContext().TraceID().String())
		c.Next()
		span.SetAttributes(
			semconv.HTTPStatusCodeKey.Int64(int64(c.Writer.Status())),
		)
		span.End()
	}
}
